#!/bin/bash
# {{ ansible_managed }}
# ============================================================================
# 备份状态检查脚本 - Backup Status Check Script
# ============================================================================
# 功能说明 - Features:
#   - 检查备份服务状态 - Check backup service status
#   - 监控磁盘使用情况 - Monitor disk usage
#   - 验证备份文件完整性 - Verify backup file integrity
#   - 显示最近备份信息 - Display recent backup information
#   - 生成状态报告 - Generate status reports
#   - 彩色输出支持 - Colored output support
# 
# 使用方法 - Usage:
#   ./backup_status.sh [options]
#   选项 - Options:
#     --json    输出JSON格式 - Output in JSON format
#     --quiet   静默模式 - Quiet mode
#     --detail  详细模式 - Detailed mode
# 
# 依赖工具 - Dependencies:
#   - systemctl (服务状态检查)
#   - df (磁盘使用检查)
#   - jq (JSON处理，可选)
# ============================================================================

# ============================================================================
# 配置变量 - Configuration Variables
# ============================================================================

# 备份根目录，存储所有备份文件 - Base directory for all backup files
BACKUP_BASE_DIR="{{ backup_base_dir }}"

# 备份日志目录，存储备份过程日志 - Directory for backup process logs
BACKUP_LOG_DIR="{{ backup_log_dir }}"

# 状态文件路径，JSON格式的备份状态信息 - Status file path with backup status in JSON format
STATUS_FILE="{{ backup_base_dir }}/status/backup_status.json"

# 备份配置文件路径 - Backup configuration file path
CONFIG_FILE="{{ backup_config_file }}"

# ============================================================================
# 颜色定义 - Color Definitions
# ============================================================================
# 用于彩色终端输出的ANSI颜色代码 - ANSI color codes for colored terminal output
RED='\033[0;31m'     # 红色，用于错误信息 - Red for error messages
GREEN='\033[0;32m'   # 绿色，用于成功信息 - Green for success messages
YELLOW='\033[1;33m'  # 黄色，用于警告信息 - Yellow for warning messages
BLUE='\033[0;34m'    # 蓝色，用于信息提示 - Blue for informational messages
NC='\033[0m'         # 无颜色，重置颜色 - No color, reset color

# ============================================================================
# 工具函数 - Utility Functions
# ============================================================================

# 彩色状态输出函数 - Colored status output function
# 参数 - Parameters:
#   $1 - 状态类型 - Status type (OK/HEALTHY/WARNING/ERROR/CRITICAL/INFO)
#   $2 - 消息内容 - Message content
# 功能 - Function: 根据状态类型显示带颜色和图标的消息
print_status() {
    local status="$1"
    local message="$2"
    
    case "$status" in
        "OK"|"HEALTHY")
            echo -e "${GREEN}✓${NC} $message"  # 绿色勾号表示正常
            ;;
        "WARNING")
            echo -e "${YELLOW}⚠${NC} $message"  # 黄色警告符号
            ;;
        "ERROR"|"CRITICAL")
            echo -e "${RED}✗${NC} $message"    # 红色叉号表示错误
            ;;
        "INFO")
            echo -e "${BLUE}ℹ${NC} $message"    # 蓝色信息符号
            ;;
        *)
            echo "$message"                     # 默认无颜色输出
            ;;
    esac
}

# 字节格式化函数 - Byte formatting function
# 参数 - Parameters:
#   $1 - 字节数 - Number of bytes
# 功能 - Function: 将字节数转换为人类可读的格式（B/KB/MB/GB/TB）
# 返回 - Returns: 格式化后的字符串
format_bytes() {
    local bytes=$1
    local units=("B" "KB" "MB" "GB" "TB")
    local unit=0
    
    # 循环除以1024直到找到合适的单位
    while [ $bytes -gt 1024 ] && [ $unit -lt 4 ]; do
        bytes=$((bytes / 1024))
        unit=$((unit + 1))
    done
    
    echo "${bytes}${units[$unit]}"
}

# 备份文件年龄计算函数 - Backup file age calculation function
# 参数 - Parameters:
#   $1 - 备份文件路径 - Backup file path
# 功能 - Function: 计算备份文件的年龄（小时数）
# 返回 - Returns: 文件年龄（小时），文件不存在时返回999
get_backup_age() {
    local backup_file="$1"
    if [ -f "$backup_file" ]; then
        # 获取文件修改时间戳
        local file_time=$(stat -c %Y "$backup_file" 2>/dev/null || echo "0")
        local current_time=$(date +%s)
        # 计算时间差并转换为小时
        local age_hours=$(( (current_time - file_time) / 3600 ))
        echo $age_hours
    else
        echo "999"  # 文件不存在时返回999小时
    fi
}

# ============================================================================
# 服务状态检查函数 - Service Status Check Functions
# ============================================================================

# 备份服务状态检查函数 - Backup service status check function
# 功能 - Function: 检查备份相关服务的运行状态
# 检查项目 - Check items:
#   - 备份监控定时器状态 - Backup monitor timer status
#   - Cron服务状态 - Cron service status
#   - 当前运行的备份进程 - Currently running backup processes
check_backup_services() {
    echo -e "\n${BLUE}=== Backup Services Status ===${NC}"
    
    # 检查备份监控定时器状态 - Check backup monitor timer
    if systemctl is-active --quiet backup-monitor.timer; then
        print_status "OK" "Backup monitor timer is active"
    else
        print_status "WARNING" "Backup monitor timer is not active"
    fi
    
    # 检查Cron服务状态 - Check cron service
    # 支持不同系统的cron服务名称
    if systemctl is-active --quiet cron || systemctl is-active --quiet crond; then
        print_status "OK" "Cron service is running"
    else
        print_status "ERROR" "Cron service is not running"
    fi
    
    # 检查当前运行的备份进程 - Check for backup processes
    local backup_processes=$(pgrep -f "backup.sh" | wc -l)
    if [ $backup_processes -gt 0 ]; then
        print_status "INFO" "$backup_processes backup process(es) currently running"
    else
        print_status "INFO" "No backup processes currently running"
    fi
}

# 磁盘使用情况检查函数 - Disk usage check function
# 功能 - Function: 检查备份目录的磁盘使用情况和各类型备份的大小
# 检查项目 - Check items:
#   - 备份分区磁盘使用率 - Backup partition disk usage
#   - 各备份类型目录大小 - Size of each backup type directory
#   - 备份文件数量统计 - Count of backup files
check_disk_usage() {
    echo -e "\n${BLUE}=== Disk Usage ===${NC}"
    
    if [ -d "$BACKUP_BASE_DIR" ]; then
        # 获取磁盘使用率和可用空间 - Get disk usage and available space
        local usage=$(df "$BACKUP_BASE_DIR" | awk 'NR==2 {print $5}' | sed 's/%//')
        local available=$(df -h "$BACKUP_BASE_DIR" | awk 'NR==2 {print $4}')
        
        # 根据使用率显示不同状态 - Display different status based on usage
        if [ $usage -lt 80 ]; then
            print_status "OK" "Disk usage: ${usage}% (${available} available)"
        elif [ $usage -lt 90 ]; then
            print_status "WARNING" "Disk usage: ${usage}% (${available} available)"
        else
            print_status "ERROR" "Disk usage: ${usage}% (${available} available) - CRITICAL"
        fi
        
        # 显示各备份目录大小 - Show backup directory sizes
        echo -e "\n${BLUE}Backup Directory Sizes:${NC}"
        for dir in daily weekly monthly; do
            local dir_path="$BACKUP_BASE_DIR/$dir"
            if [ -d "$dir_path" ]; then
                # 计算目录大小和文件数量
                local size=$(du -sh "$dir_path" 2>/dev/null | cut -f1)
                local count=$(find "$dir_path" -type f -name "*.tar.gz" -o -name "*.gz" | wc -l)
                echo "  $dir: $size ($count files)"
            fi
        done
    else
        print_status "ERROR" "Backup directory $BACKUP_BASE_DIR does not exist"
    fi
}

# 最近备份状态检查函数 - Recent backup status check function
# 功能 - Function: 检查各类型备份的最新状态和时效性
# 检查项目 - Check items:
#   - 每日备份状态 - Daily backup status
#   - 每周备份状态 - Weekly backup status
#   - 每月备份状态 - Monthly backup status
#   - 备份文件年龄和大小 - Backup file age and size
check_recent_backups() {
    echo -e "\n${BLUE}=== Recent Backup Status ===${NC}"
    
    local backup_types=("daily" "weekly" "monthly")
    
    for backup_type in "${backup_types[@]}"; do
        local backup_dir="$BACKUP_BASE_DIR/$backup_type"
        if [ -d "$backup_dir" ]; then
            # 查找最新的备份文件 - Find the latest backup file
            local latest_backup=$(find "$backup_dir" -name "*.tar.gz" -type f -printf '%T@ %p\n' 2>/dev/null | sort -n | tail -1 | cut -d' ' -f2-)
            
            if [ -n "$latest_backup" ]; then
                # 获取备份文件信息 - Get backup file information
                local age_hours=$(get_backup_age "$latest_backup")
                local backup_name=$(basename "$latest_backup")
                local backup_size=$(du -h "$latest_backup" 2>/dev/null | cut -f1)
                
                # 设置不同备份类型的时效阈值 - Set age thresholds for different backup types
                case $backup_type in
                    "daily")
                        local threshold=25    # 25小时 - 25 hours
                        ;;
                    "weekly")
                        local threshold=168   # 7天 - 7 days
                        ;;
                    "monthly")
                        local threshold=744   # 31天 - 31 days
                        ;;
                esac
                
                # 根据备份年龄判断状态 - Determine status based on backup age
                if [ $age_hours -lt $threshold ]; then
                    print_status "OK" "$backup_type: $backup_name (${age_hours}h ago, $backup_size)"
                else
                    print_status "WARNING" "$backup_type: $backup_name (${age_hours}h ago, $backup_size) - OVERDUE"
                fi
            else
                print_status "ERROR" "$backup_type: No backups found"
            fi
        else
            print_status "WARNING" "$backup_type: Directory $backup_dir does not exist"
        fi
    done
}

# 备份完整性检查函数 - Backup integrity check function
# 功能 - Function: 验证备份文件的完整性和可用性
# 检查项目 - Check items:
#   - tar.gz文件完整性 - tar.gz file integrity
#   - gz文件完整性 - gz file integrity
#   - 损坏文件统计 - Corrupted file statistics
check_backup_integrity() {
    echo -e "\n${BLUE}=== Backup Integrity Check ===${NC}"
    
    local total_files=0
    local corrupted_files=0
    
    # 遍历所有备份类型目录 - Iterate through all backup type directories
    for backup_type in daily weekly monthly; do
        local backup_dir="$BACKUP_BASE_DIR/$backup_type"
        if [ -d "$backup_dir" ]; then
            # 使用null分隔符处理文件名，避免空格问题 - Use null separator for filenames to avoid space issues
            while IFS= read -r -d '' file; do
                total_files=$((total_files + 1))
                # 检查tar.gz文件完整性 - Check tar.gz file integrity
                if [[ "$file" == *.tar.gz ]]; then
                    if ! tar -tzf "$file" >/dev/null 2>&1; then
                        corrupted_files=$((corrupted_files + 1))
                        print_status "ERROR" "Corrupted: $(basename "$file")"
                    fi
                # 检查gz文件完整性 - Check gz file integrity
                elif [[ "$file" == *.gz ]]; then
                    if ! gzip -t "$file" 2>/dev/null; then
                        corrupted_files=$((corrupted_files + 1))
                        print_status "ERROR" "Corrupted: $(basename "$file")"
                    fi
                fi
            done < <(find "$backup_dir" -type f \( -name "*.tar.gz" -o -name "*.gz" \) -print0 2>/dev/null)
        fi
    done
    
    # 根据检查结果显示状态 - Display status based on check results
    if [ $total_files -eq 0 ]; then
        print_status "WARNING" "No backup files found for integrity check"
    elif [ $corrupted_files -eq 0 ]; then
        print_status "OK" "All $total_files backup files passed integrity check"
    else
        print_status "ERROR" "$corrupted_files out of $total_files backup files are corrupted"
    fi
}

# 配置状态检查函数 - Configuration status check function
# 功能 - Function: 检查备份系统的配置状态和脚本可用性
# 检查项目 - Check items:
#   - 配置文件存在性 - Configuration file existence
#   - 关键配置项状态 - Key configuration settings
#   - 备份脚本可用性 - Backup script availability
check_configuration() {
    echo -e "\n${BLUE}=== Configuration Status ===${NC}"
    
    if [ -f "$CONFIG_FILE" ]; then
        print_status "OK" "Configuration file exists: $CONFIG_FILE"
        
        # 检查关键配置项 - Check key configuration values
        if grep -q "BACKUP_ENABLED=true" "$CONFIG_FILE" 2>/dev/null; then
            print_status "OK" "Backup is enabled"
        else
            print_status "WARNING" "Backup may be disabled"
        fi
        
        if grep -q "ENCRYPTION_ENABLED=true" "$CONFIG_FILE" 2>/dev/null; then
            print_status "OK" "Encryption is enabled"
        else
            print_status "INFO" "Encryption is disabled"
        fi
        
        if grep -q "COMPRESSION_ENABLED=true" "$CONFIG_FILE" 2>/dev/null; then
            print_status "OK" "Compression is enabled"
        else
            print_status "INFO" "Compression is disabled"
        fi
    else
        print_status "ERROR" "Configuration file not found: $CONFIG_FILE"
    fi
    
    # 检查备份脚本可用性 - Check backup scripts
    local scripts=("backup.sh" "restore.sh" "verify.sh" "cleanup.sh" "backup_monitor.sh")
    for script in "${scripts[@]}"; do
        local script_path="{{ backup_scripts_dir }}/$script"
        if [ -f "$script_path" ] && [ -x "$script_path" ]; then
            print_status "OK" "Script available: $script"
        else
            print_status "ERROR" "Script missing or not executable: $script"
        fi
    done
}

# 日志检查函数 - Log check function
# 功能 - Function: 检查备份系统的日志文件状态和错误信息
# 检查项目 - Check items:
#   - 日志文件存在性 - Log file existence
#   - 日志文件大小 - Log file size
#   - 错误和警告计数 - Error and warning counts
check_logs() {
    echo -e "\n${BLUE}=== Recent Log Activity ===${NC}"
    
    local log_files=("backup.log" "backup_monitor.log" "error.log")
    
    for log_file in "${log_files[@]}"; do
        local log_path="$BACKUP_LOG_DIR/$log_file"
        if [ -f "$log_path" ]; then
            # 获取日志文件信息 - Get log file information
            local log_size=$(du -h "$log_path" 2>/dev/null | cut -f1)
            local recent_errors=$(grep -c "ERROR" "$log_path" 2>/dev/null || echo "0")
            local recent_warnings=$(grep -c "WARNING" "$log_path" 2>/dev/null || echo "0")
            
            # 根据错误和警告数量显示状态 - Display status based on error and warning counts
            if [ $recent_errors -gt 0 ]; then
                print_status "ERROR" "$log_file: $log_size, $recent_errors errors, $recent_warnings warnings"
            elif [ $recent_warnings -gt 0 ]; then
                print_status "WARNING" "$log_file: $log_size, $recent_warnings warnings"
            else
                print_status "OK" "$log_file: $log_size, no recent issues"
            fi
        else
            print_status "WARNING" "Log file not found: $log_file"
        fi
    done
    
    # Show last few log entries
    local main_log="$BACKUP_LOG_DIR/backup.log"
    if [ -f "$main_log" ]; then
        echo -e "\n${BLUE}Last 5 backup log entries:${NC}"
        tail -5 "$main_log" 2>/dev/null | while read -r line; do
            echo "  $line"
        done
    fi
}

# 备份计划显示函数 - Backup schedule display function
# 功能 - Function: 显示当前配置的备份计划和定时任务
# 检查项目 - Check items:
#   - Cron定时任务 - Cron scheduled jobs
#   - Systemd定时器状态 - Systemd timer status
show_backup_schedule() {
    echo -e "\n${BLUE}=== Backup Schedule ===${NC}"
    
    # 检查备份用户的cron任务 - Check cron jobs for backup user
    local backup_user="{{ backup_user | default('root') }}"
    local cron_jobs=$(crontab -u "$backup_user" -l 2>/dev/null | grep -v "^#" | grep "backup.sh" || echo "")
    
    if [ -n "$cron_jobs" ]; then
        echo "Scheduled backup jobs:"
        echo "$cron_jobs" | while read -r job; do
            echo "  $job"
        done
    else
        print_status "WARNING" "No backup cron jobs found for user $backup_user"
    fi
    
    # 显示systemd定时器状态 - Show systemd timer status
    if systemctl list-timers backup-monitor.timer >/dev/null 2>&1; then
        echo -e "\nSystemd timer status:"
        systemctl list-timers backup-monitor.timer --no-pager 2>/dev/null | tail -n +2
    fi
}

# 整体状态显示函数 - Overall status display function
# 功能 - Function: 显示备份系统的整体健康状态
# 数据源 - Data source: 从JSON状态文件读取系统状态信息
# 状态级别 - Status levels: healthy, warning, critical, unknown
show_overall_status() {
    echo -e "\n${BLUE}=== Overall Backup System Status ===${NC}"
    
    # 从JSON状态文件读取状态信息（如果可用）- Read status from JSON file if available
    if [ -f "$STATUS_FILE" ] && command -v jq >/dev/null 2>&1; then
        local backup_status=$(jq -r '.backup_status // "unknown"' "$STATUS_FILE" 2>/dev/null)
        local last_check=$(jq -r '.last_check // "unknown"' "$STATUS_FILE" 2>/dev/null)
        local disk_usage=$(jq -r '.disk_usage // "unknown"' "$STATUS_FILE" 2>/dev/null)
        
        # 根据状态级别显示相应的状态信息 - Display status information based on status level
        case "$backup_status" in
            "healthy")
                print_status "OK" "System Status: HEALTHY"
                ;;
            "warning")
                print_status "WARNING" "System Status: WARNING - Attention Required"
                ;;
            "critical")
                print_status "ERROR" "System Status: CRITICAL - Immediate Action Required"
                ;;
            *)
                print_status "INFO" "System Status: UNKNOWN"
                ;;
        esac
        
        echo "Last Check: $last_check"
        echo "Disk Usage: ${disk_usage}%"
    else
        print_status "INFO" "Status file not available or jq not installed"
    fi
}

# 主函数 - Main function
# 功能 - Function: 执行完整的备份系统状态检查
# 检查流程 - Check process:
#   1. 显示系统整体状态 - Display overall system status
#   2. 检查备份服务状态 - Check backup service status
#   3. 检查磁盘使用情况 - Check disk usage
#   4. 检查最近备份状态 - Check recent backup status
#   5. 验证备份文件完整性 - Verify backup file integrity
#   6. 检查配置文件 - Check configuration files
#   7. 检查日志文件 - Check log files
#   8. 显示备份计划 - Show backup schedule
main() {
    echo -e "${BLUE}╔══════════════════════════════════════════════════════════════╗${NC}"
    echo -e "${BLUE}║                    BACKUP SYSTEM STATUS                     ║${NC}"
    echo -e "${BLUE}║                    $(date '+%Y-%m-%d %H:%M:%S')                    ║${NC}"
    echo -e "${BLUE}╚══════════════════════════════════════════════════════════════╝${NC}"
    
    # 执行各项状态检查 - Execute various status checks
    show_overall_status
    check_backup_services
    check_disk_usage
    check_recent_backups
    check_backup_integrity
    check_configuration
    check_logs
    show_backup_schedule
    
    # 显示常用命令提示 - Display common command hints
    echo -e "\n${BLUE}=== Quick Commands ===${NC}"
    echo "Manual backup:     {{ backup_scripts_dir }}/backup.sh [daily|weekly|monthly]"
    echo "Restore backup:    {{ backup_scripts_dir }}/restore.sh --help"
    echo "Verify backups:    {{ backup_scripts_dir }}/verify.sh"
    echo "Cleanup old:       {{ backup_scripts_dir }}/cleanup.sh"
    echo "Monitor logs:      tail -f $BACKUP_LOG_DIR/backup.log"
    
    echo -e "\n${BLUE}Status check completed at $(date)${NC}"
}

# 命令行参数处理 - Handle command line arguments
# 支持的参数 - Supported arguments:
#   -h, --help    : 显示帮助信息 - Show help message
#   -q, --quiet   : 静默模式，只显示错误和警告 - Quiet mode, show only errors and warnings
#   -s, --summary : 摘要模式，只显示关键信息 - Summary mode, show only key information
case "${1:-}" in
    "-h"|"--help")
        echo "Usage: $0 [options]"
        echo "Options:"
        echo "  -h, --help     Show this help message"
        echo "  -q, --quiet    Show only errors and warnings"
        echo "  -s, --summary  Show only summary information"
        exit 0
        ;;
    "-q"|"--quiet")
        # 重定向信息消息到/dev/null，只保留错误和警告 - Redirect info messages to /dev/null
        exec 3>&1
        exec 1>/dev/null
        main
        exec 1>&3
        ;;
    "-s"|"--summary")
        # 摘要模式：只显示整体状态和最近备份信息 - Summary mode: show only overall status and recent backup info
        show_overall_status
        check_recent_backups
        ;;
    *)
        # 默认模式：执行完整的状态检查 - Default mode: execute full status check
        main
        ;;
esac